package cn.rkylin.oms.base.refundReasonType.utils.apprhandler;

import cn.rkylin.oms.warehouse.returnStockin.dao.ReturnStockinSkuDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.greenpineyu.fel.common.StringUtils;

import cn.rkylin.oms.aftersale.sysrefund.servcie.ISysRefundService;
import cn.rkylin.oms.aftersale.sysrefund.vo.SysRefundVO;
import cn.rkylin.oms.base.refundReasonType.service.RdfundReasonTypeService;
import cn.rkylin.oms.base.refundReasonType.utils.RuleParseUtil;
import cn.rkylin.oms.common.consts.YesNoConst;

/**
 * 类名:ApprHandler <br/>
 * 作用: 退款单退款原因审核责任链抽象类. <br/>
 * 创建时间:     2017年11月3日 下午2:30:38 <br/>
 * @author   zhanghao
 * @version  v1.0 
 */
@Service
public abstract class ApprHandler extends SpringBeanAutowiringSupport{
    protected static final String MSG_SUCCESS = "SUCCESS";
    protected static final String MSG_FAILED = "FAILED";
    protected static final String MSG_CONFIRM = "CONFIRM";
    
    protected ApprHandler successor;
    protected int maxLength = RuleParseUtil.maxLength;
    
    private JSONObject contextObj = null;
    
    public JSONObject getContextObj() {
        return contextObj;
    }

    private void setContextObj(JSONObject contextObj) {
        this.contextObj = contextObj;
    }

    @Autowired
    protected RdfundReasonTypeService rdfundReasonTypeService;

    @Autowired
    protected ReturnStockinSkuDAO returnStockinSkuDAO;
    
    /**
     * sysRefundService:系统退款单服务层.
     */
    @Autowired
    protected ISysRefundService sysRefundService;

    public ApprHandler(){

    }

    public void finalize() throws Throwable {

    }

    /**
     * 
     * @param successor
     */
    public void SetSuccessor(ApprHandler successor){
        if(this.contextObj==null&&successor!=null) {
            this.contextObj = new JSONObject();
            JSONObject result = new JSONObject();
            JSONArray detail = new JSONArray();
            result.put("detail", detail);
            result.put("result", "");
            result.put("message", "");
            JSONObject param = new JSONObject();
            
            this.contextObj.put("result", result);
            this.contextObj.put("param", param);
            successor.setContextObj(this.contextObj);
        }
        this.successor = successor;
    }

    protected JSONObject getSuccessJson(SysRefundVO sysRefundVO,JSONObject result) {
        JSONObject temp = new JSONObject();
        temp.put("validresult", "success");
        temp.put("rulecontent", getRuleContent());
        return result;
    }
    
    /**
     * getRuleContent:获取规则内容. <br/>
     *
     * @author zhanghao
     * @return
     */
    protected abstract String getRuleContent();
    
    protected JSONObject getFailedJson(SysRefundVO sysRefundVO,JSONObject result) {
        return result;
    }

    
    /**
     * @throws Exception 
     * @see cn.rkylin.oms.base.refundReasonType.utils.apprhandler.ApprHandler#HandleRequest(cn.rkylin.oms.aftersale.sysrefund.vo.SysRefundVO, com.alibaba.fastjson.JSONObject)
     */
    public void HandleRequest(final SysRefundVO sysRefundVO,JSONObject contextObj) throws Exception {
        if(null!=contextObj) {
            this.contextObj = contextObj;
        }
        // 判断是否需要执行此校验，以及此校验是否通过
        if(isValidSuitable()) {
            if(isValid(sysRefundVO)) {
                setJsonMessage(MSG_SUCCESS,getRuleContent());
            }else {
                setJsonMessage(getRuleLevel(),getRuleContent());
            }
        }
        if(null!=successor) {
            successor.HandleRequest(sysRefundVO,this.contextObj);
        }
    }
    
    /**
     * getRuleLevel:获取校验规则的级别. <br/>
     *
     * @author zhanghao
     * @return
     */
    protected String getRuleLevel() {
        String returnResult = MSG_FAILED;
        JSONObject paramObject = this.contextObj.getJSONObject("param");
        // 如果本次审核是强制审核，就将level设置为confirm，否则将level设置为failed
        if(YesNoConst.YES.equalsIgnoreCase(paramObject.getString("forceAppr"))&&YesNoConst.YES.equalsIgnoreCase(paramObject.getString("isForceAppr"))) {
            returnResult = MSG_CONFIRM;
        }
        return returnResult;
    }

    private void setJsonMessage(String result,String message) {
        JSONObject resultObject = this.contextObj.getJSONObject("result");
        
        JSONObject detailObject = new JSONObject();
        detailObject.put("result", result);
        detailObject.put("message", message);
        
        // 如果result为空，或者result的优先级高于现有优先级时，赋值高优先级（failed>confirm>success>""）
        if(StringUtils.isEmpty(resultObject.getString("result"))
                ||resultObject.getString("result").equalsIgnoreCase(MSG_SUCCESS)&&!result.equalsIgnoreCase(MSG_SUCCESS)
                ||resultObject.getString("result").equalsIgnoreCase(MSG_CONFIRM)&&result.equalsIgnoreCase(MSG_FAILED)
                ) {
            resultObject.put("result", result);
        }
        JSONArray detailArray = resultObject.getJSONArray("detail");
        detailArray.add(detailObject);
        resultObject.put("detail", detailArray);
        this.contextObj.put("result", resultObject);
    }
    
    /**
     * isValid:检查校验是否通过. <br/>
     *
     * @author zhanghao
     * @param sysRefundVO
     * @return
     */
    protected abstract boolean isValid(SysRefundVO sysRefundVO) throws Exception;
    
    /**
     * isValidSuitable:启用校验规则，则返回true；否则返回false. <br/>
     *
     * @author zhanghao
     * @param apprRule
     * @return
     * @throws Exception
     */
    protected boolean isValidSuitable() throws Exception {
        String apprRule = contextObj.getJSONObject("param").getString("apprRule");
        boolean result = true;
        int[] ruleCheckArray = getRuleCheckArray();
        if(StringUtils.isNotEmpty(apprRule)&&ruleCheckArray.length>0) {
            for (int index : ruleCheckArray ) {
                // 如果没有规则，就不校验
                // 如果有规则，但某对应项的规则数是0，不校验
                // 如果有规则，但对应不上，不校验
                if (StringUtils.isEmpty(apprRule) || apprRule.length() < (maxLength - index)||(apprRule.length()>= (maxLength - index) && apprRule.charAt(maxLength - index) != '1')) {
                    result = false;
                    break;
                }
            }
        }
        return result;
    }

    /**
     * getRuleCheckArray:获取条件校验数组. <br/>
     *
     * @author zhanghao
     * @return
     */
    protected abstract int[] getRuleCheckArray();
}

